package com.xbongbong.formula.qlexpress.operator.math;

import com.ql.util.express.Operator;
import com.ql.util.express.OperatorOfNumber;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.MathUtil;
import com.xbongbong.pro.enums.ErrorCodeEnum;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * @author: wufeng
 * @date: 2018/7/4 17:18
 * @desrcption: 语法: ROUNDDOWN(number, num_digits)
 * 说明：number为要处理的数字，num_digits为指定小数位数
 * • ROUNDDOWN 的行为与 ROUND 相似，所不同的是它始终将数字进行向下舍入。
 * • 如果 num_digits 大于 0（零），则将数字向下舍入到指定的小数位数。
 * • 如果 num_digits 为 0，则将数字向下舍入到最接近的整数。
 * • 如果 num_digits 小于 0，则将数字向下舍入到小数点左边的相应位数。
 */
public class OperatorRoundDown extends Operator {

    public OperatorRoundDown(String name){
        this.name = name;
    }

    public OperatorRoundDown(String aliasName, String aName, String errorInfo){
        this.aliasName = aliasName;
        this.name = aName;
        this.errorInfo = errorInfo;
    }

    @Override
    public Object executeInner(Object[] list) throws Exception {
        Object value = list[0];
        Integer numDigits = 0;
        if (list.length == Constant.LENGTH) {
            numDigits = Integer.valueOf(String.valueOf(list[1]));
        }
        if (numDigits < 0 || numDigits == 0) {
            Number result = OperatorOfNumber.divide(Math.floor(Double.valueOf(String.valueOf(value)) * Math.pow(10, numDigits)) , Math.pow(10, numDigits), true);
            if (Objects.isNull(result)) {
                return null;
            }
            long tempLong = MathUtil.ceil(result, 0).longValue();
            if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
                return (int)tempLong;
            }else{
                return tempLong;
            }
        } else {
            Number result;
            Double num = Double.valueOf(String.valueOf(value));
            if (num < 0) {
                result = OperatorOfNumber.divide(Math.ceil(num * Math.pow(10, numDigits)) , Math.pow(10, numDigits), true);
            } else {
                result = OperatorOfNumber.divide(Math.floor(num * Math.pow(10, numDigits)) , Math.pow(10, numDigits), true);
            }
            BigDecimal bigDecimal = MathUtil.ceil(result.doubleValue(), numDigits);
            if (bigDecimal.scale() == 0) {
                long tempLong = bigDecimal.longValue();
                if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
                    return (int)tempLong;
                }else{
                    return tempLong;
                }
            }
            return bigDecimal.doubleValue();
        }
    }
}
